package com.zx.mes.disk.hyl.controller;

import com.zx.mes.disk.hyl.pagemodel.FileEntity;
import com.zx.mes.disk.hyl.utils.ZipUtils;
import com.zx.mes.hyl.common.msg.ObjectRestResponse;
import com.zx.mes.hyl.common.msg.TableResultResponse;
import com.zx.mes.hyl.common.util.DateUtil;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * 文件上传控制器  http://www.jb51.net/article/106842.htm
 * https://github.com/axios/axios/issues/448   axios 不能下载问题解决
 * @author hyl
 * @date 2018-5-2
 */

@RestController
@RequestMapping("/fileUploadController")
public class FileUploadController {

    private final static Logger logger = LoggerFactory.getLogger(FileUploadController.class);

    private static String UPLOADED_FOLDER = "D://AP//";

    @GetMapping("/zipDownload")
    public void zip(HttpServletResponse response,String filePath){

        // response 重置
        response.reset();
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM.toString());
        // 设置强制下载不打开
        response.setContentType("application/force-download");

//        response.addHeader("Content-Length", "" + size);
        response.setContentType("application/octet-stream; charset=UTF-8");
        File f = new File(filePath);
        String fileName = f.getName();
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
//        response.setHeader("Access-Control-Allow-Headers", "'Content-Disposition'");
        response.setHeader("Content-Disposition", "attachment; filename=\""+ fileName + "\"");


        long size = 0;
        // nio 遍历文件
        final List<File> files = new ArrayList<File>();
        SimpleFileVisitor<Path> finder = new SimpleFileVisitor<Path>(){
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                files.add(file.toFile());
                return super.visitFile(file, attrs);
            }

            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                files.add(dir.toFile());
                return super.postVisitDirectory(dir, exc);
            }
        };

        try {
            Files.walkFileTree(Paths.get(filePath), finder);

            ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream(), Charset.forName("UTF-8"));

//            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
//            ZipOutputStream zip = new ZipOutputStream(outputStream);

            for (File file : files) {
                ZipEntry zipEntry = new ZipEntry(file.getName());
                logger.info(file.getPath());
                zipOutputStream.putNextEntry(zipEntry);
                Files.copy(Paths.get(file.getPath()), zipOutputStream);
            }
//            IOUtils.write(outputStream.toByteArray(), response.getOutputStream());
            zipOutputStream.closeEntry();
            zipOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @GetMapping("/zipDownload2")
    public void zip2(HttpServletResponse response,String filePath){

        // response 重置
        response.reset();
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM.toString());
        // 设置强制下载不打开
        response.setContentType("application/force-download");

        response.setContentType("application/octet-stream; charset=UTF-8");
        File f = new File(filePath);
        String fileName = f.getName();
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Content-Disposition", "attachment; filename=\""+ fileName + "\"");

        /** 4.调用工具类，下载zip压缩包 */
        // 这里我们不需要保留目录结构
        try {
            ZipUtils.toZip(f.getPath(), response.getOutputStream(),true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @PostMapping("/upload2")
    @ResponseBody
    public ObjectRestResponse<String> upload2(@RequestParam("file") MultipartFile file,HttpServletRequest request) {
        MultipartHttpServletRequest params=((MultipartHttpServletRequest) request);
        String relativePath = params.getParameter("relativePath");
        logger.info("文件相对路径:"+params.getParameter("relativePath"));
        ObjectRestResponse<String> response = new ObjectRestResponse<>();
        logger.info("文件上传成功:"+file.getOriginalFilename());
        if (file.isEmpty()) {
            response.data("空文件夹!").rel(true);
        }

        try {
            byte[] bytes = file.getBytes();

            File dest = new File(UPLOADED_FOLDER + relativePath);
            if (!dest.getParentFile().exists()) {
                dest.getParentFile().mkdirs();
            }
            Path path = Paths.get(UPLOADED_FOLDER + relativePath);
            Files.write(path, bytes);
            response.data("上传成功").rel(true);
        } catch (FileNotFoundException e) {
            response.data("上传失败").rel(true);
            e.printStackTrace();
        } catch (IOException e) {
            response.data("上传失败").rel(true);
            e.printStackTrace();
        }


        return response;
    }


    @GetMapping("/list")
    @ResponseBody
    public TableResultResponse<FileEntity> fileList(FileEntity fileEntity,int page,int limit){

        List<FileEntity> fileEntityList = new ArrayList<>(20);
        // file为空时，那么就是在根目录下
        File file = null;
        File[] files = null;
        if (fileEntity != null && fileEntity.getFilePath()==null) {
            file = new File(UPLOADED_FOLDER);
            files = file.listFiles();
        }else if (!fileEntity.getFilePath().equalsIgnoreCase("")){
            file = new File(fileEntity.getFilePath());
            files = file.listFiles();
        }else {

        }
        for (int i=0;i<files.length;i++) {
            FileEntity fe = new FileEntity();
            fe.setName(files[i].getName());

            fe.setModifydatetime(DateUtil.dateFormat(new Date(files[i].lastModified()), "yyyy-MM-dd HH:mm:ss"));
            fe.setFilePath(files[i].getPath());
            if (files[i].isDirectory()) {
                fe.setType("文件夹");
            }else {
                fe.setType("文件");
                // 以KB返回
                fe.setSize(files[i].length()/1024);
            }
            fileEntityList.add(fe);
        }
        int index =( page - 1)*limit;
        int total = page * limit-1;

        if (total > fileEntityList.size()) {
            total = fileEntityList.size();
        }
        List<FileEntity> list=fileEntityList.subList(index, total);
        return new TableResultResponse<>(fileEntityList.size(), list);
    }

    @PostMapping("/upload")
    @ResponseBody
    public ObjectRestResponse<String> upload(HttpServletRequest request){

        MultipartHttpServletRequest params= null;
        List<MultipartFile> files = null;
        try {
            params = ((MultipartHttpServletRequest) request);
            files = ((MultipartHttpServletRequest) request)
                    .getFiles("file");
        } catch (Exception e) {
            logger.info(e.getMessage());
            e.printStackTrace();
        }

        logger.info("MultipartHttpServletRequest name:["+params.getParameter("name")+"] id:["+params.getParameter("id"));
//        logger.info("过时rootPath:"+request.getRealPath("/"));
        logger.info("rootPath:"+request.getSession().getServletContext().getRealPath("/"));
        logger.info("rootUrl:"+request.getContextPath());
        ObjectRestResponse<String> response = new ObjectRestResponse<>();
        MultipartFile file = null;
        // 1.没有文件上传的情况
        if (files!=null && files.size()==0){
            response.data("没有可上传的文件!").rel(true);
        }else {
            logger.info("文件数目:"+files.size());
            for (int i=0;i<files.size();i++) {
                file = files.get(i);
                if (!file.isEmpty()){
                    logger.info(file.getOriginalFilename()+ " "+file.getSize());
                    response.data("上传成功!").rel(true);
                }else {
                    response.data("上传的文件夹为空!").rel(true);
                }
            }
        }

        return response;
    }

    @GetMapping("/test")
    @ResponseBody
    public ObjectRestResponse<String> test(){
        return new ObjectRestResponse<>().rel(true).data("test");
    }
}
